﻿/* Script permettant la création des maps de jeu*/

/* 
 * @function :
 * @param : imgRepository -> éléments composant la map
 */
function Map(imgRepository) {

    this._map = null;
    this._goals = 0;
    this._goalsAchived = 0;
    this._width = 0;
    this._height = 0;
    this._playerX = 0;
    this._playerY = 0;
    this.Number = 0;
    this.Finished = false;
    this.OnScreenWidht = 0;
    this.OnScreenHeight = 0;
    this.ImageRepository = imgRepository;					// Instance des images constituant la map
    var _levelStatistics = new LevelStatistics(this);		// Statistique de la map
    this.Loaded = false;									// Booléen : si la map est chargé

	/* 
	 * @function : Retourne la position du joueur sur la map 
	 */
    this.GetPlayer = function () { 
        return this._map[this._playerX][this._playerY];
    }

	/* 
	 * @function : Charge la map du level souhaité
	 */
    this.LoadMap = function (levelNumber) {
        this._map = null;
        this._goals = 0;
        this._goalsAchived = 0;
        this._width = 0;
        this._height = 0;
        this._playerX = 0;
        this._playerY = 0;
        this.Finished = false;
        this.Loaded = false;
        this.Number = levelNumber;
		
		/* Rechargement dynamique de la page */
        $.ajax({
            type: "GET",
            url: "xml/levels.xml",

            dataType: "xml",
            success: this.ParseXmlMap, // On charge les éléments de la map situé dans le XML
            context: this
        });
    }

	/* 
	 * @function : Vérifie si les conditions de fin de jeu sont remplies 
	 */
    this.Update = function () {
        if (this._goals > 0 && this._goalsAchived == this._goals) {
            this.Finished = true;
        }
        _levelStatistics.Update();
    }

	
	/* 
	 * @function : Dessine la map 
	 * @param : canvasContext -> zone du canvas
	 */
    this.Draw = function (canvasContext) {

        var xCanvasPos = 20;
        var yCanvasPos = 20;
        var tileSize = 30;
		
        for (var y = 0; y < this._height; y++) {
            xCanvasPos = 20;
            for (var x = 0; x < this._width; x++) {

                var img = this._map[x][y].GetImage();
                if (img != null) {
                    // draw image
                    canvasContext.drawImage(img, xCanvasPos, yCanvasPos);

                } else {
                    // draw rectangle
                    canvasContext.fillStyle = this._map[x][y].GetFillStyle();
                    canvasContext.fillRect(xCanvasPos, yCanvasPos, tileSize, tileSize);
                }

                xCanvasPos += tileSize;
            }
            yCanvasPos += tileSize;
        }
		
        // this is used to properly position level statistics according to the level
        this.OnScreenWidht = xCanvasPos;
        this.OnScreenHeight = yCanvasPos;
        _levelStatistics.Draw(canvasContext);
    }

	/* 
	 * @function : Parse du fichier xml pour déduire les éléments du décor 
	 * @param : xml -> fichier xml
	 */
    this.ParseXmlMap = function (xml) {
		levelNum = this.Number;
		$(xml).find('Level').each( function (){
			if($(this).attr('No') == levelNum){
				xml = this;
			}
		});
		this._width = parseFloat($(xml).attr('Width')); // on fixe la largeur de la zone de jeu
        this._height = parseFloat($(xml).attr('Height')); // on fixe la hauteur de la zone de jeu

        this._map = new Array(this._width)

        for (var x = 0; x < this._map.length; x++) {
            this._map[x] = new Array(this._height)
        }

        var y = 0;
		
        //find every Tutorial and print the author
        var mapRef = this._map;
        var mapObjectRef = this;
        var mapWidth = this._width;

		// On recherche toutes les lignes "Row" du fichier xml correspondant aux lignes de la map
		$(xml).find("Row").each(function () {
		
            var wall = false;
            var row = $(this).text();
			
            for (var x = 0; x < mapWidth; x++) {

                // Certaines lignes sont plus courtes que la largeur de la map - on remplit le reste avec des éléments vides
                if (x >= row.length) {
                    mapRef[x][y] = new Empty();

                } else {

                    switch (row[x]) {
                        case " ":
                            // Si un mur a déjà été posé cela signifie qu'il nous faut insérer un élément du sol,
                            // pour les éléments vides qui sont situés en 2 murs nous utilisons le caractère '='
                            if (wall) {
                                mapRef[x][y] = new Floor();
                            }
                            else {
                                mapRef[x][y] = new Empty();
                            }
                            break;
                        case "#": // Affichage d'un mur
                            mapRef[x][y] = new Wall();
                            wall = true;
                            break;
                        case "x": // Affichage d'un mur cassable
                            mapRef[x][y] = new WallBreakable();
                            wall = true;
                            break;
                        case "@": // Affichage d'un joueur en début de jeu
                            mapRef[x][y] = new Player(mapObjectRef);
                            mapObjectRef._playerX = x; // On fixe la position horizontal du joueur
                            mapObjectRef._playerY = y; // On fixe la position vertical du joueur
                            break;
                    }
                   

                }
				
                mapRef[x][y].ImageRepository = mapObjectRef.ImageRepository;
            }
			
            y++; // incrément de ligne pour le fichier xml (on passe à la ligne suivante
        });

		// Le chargement c'est bien déroulé
        this.Loaded = true;
    }
}